package Thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 查看电脑核数 System.out.println(Runtime.getRuntime().availableProcessors());
 * 1、核心线程数
 * 2、最大线程数
 * 3、当线程数超过核心线程数 超时时间
 * 4、超时时间单位
 * 5、阻塞队列
 * 6、线程工厂 推荐使用默认
 * 7、线程超时策略 CallerRunsPolicy:当线程超过最大线程数量 放到队列最后 不抛出异常
 * CallerRunsPolicy:当线程超过最大线程数量 回退任务给调用线程 不抛出异常（一般情况下推荐使用）
 * DiscardOldestPolicy 放弃等待时间最长的任务 尝试把当前任务提交 不抛出异常
 * DiscardPolicy 直接放弃任务 不抛出异常 （如果允许丢失任务 推荐使用）
 * AbortPolicy 当任务超过最大线程数量和队列已满 再有任务进入 直接抛出异常停止运行
 * 线程池配置合理线程数
 * （1）CPU密集
 *      一般公式：CPU核数+1个线程的线程池
 * （2）IO密集型
 *      1、由于IO密集型任务线程并不是一直执行任务，则应配置尽可能多的线程，如：CPU核数*2
 *
 *      2、IO密集型，即该任务需要大量的IO，即大量的阻塞。
 *      在单线程上运行IO密集型的任务会导致浪费大量的CPU运算能力浪费在等待。
 *      所以在IO密集型任务中使用多线程可以大大的加速程序运行，即使在单核CPU上，这种加速主要就是利用了被浪费的阻塞时间。
 *
 *      3、IO密集型时，大部分线程都阻塞，故需要多配置线程数：
 *      参考公式： CPU核数 / 1 -阻塞系数 阻塞系数在0.8~0.9之间
 */
public class MyThreadPoolDemo {
    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors()+1,Runtime.getRuntime().availableProcessors()+1,60,TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.CallerRunsPolicy());

        for (int j = 0; j <1000 ; j++) {
            int finalJ = j;
            threadPoolExecutor.execute(()->{
                System.out.println("线程池使用"+ finalJ);
            });
        }


    }
}
